class BluetoothPrinter {
  constructor() {
    this.deviceId = ''; // 连接的设备ID
    this.serviceId = ''; // 蓝牙服务UUID
    this.characteristicId = ''; // 蓝牙特征值UUID
    this.connected = false; // 连接状态
    this.deviceList = []; // 发现的设备列表
    this.callbacks = { // 回调函数集合
      onDeviceFound: null,
      onStatusChange: null,
      onConnected: null,
      onDisconnected: null,
      onStopSearch: null
    };
    this.timer = null;
  }

  /**
   * 初始化蓝牙模块
   */
  initBluetooth() {
    return new Promise((resolve, reject) => {
      wx.openBluetoothAdapter({
        success: (res) => {
          this._setStatus('蓝牙适配器初始化成功');
          resolve(res);
          console.log('蓝牙适配器初始化成功');
          // this.searchDevices();
        },
        fail: (err) => {
          this._setStatus('蓝牙初始化失败，请检查手机蓝牙是否开启');
          reject(err);
          console.log('初始化失败:', err);
        }
      });
    });
  }

  /**
   * 搜索蓝牙设备
   */
  searchDevices(serviceUUIDs = ['E7810A71-73AE-499D-8C15-FAA9AEF0C3F2']) {
    return new Promise((resolve, reject) => {
      wx.startBluetoothDevicesDiscovery({
        services: serviceUUIDs, // 指定服务UUID过滤打印机设备
        // services: ['0000FDAA-0000-1000-8000-00805F9B34FB'],
        // allowDuplicatesKey: false,
        success: (res) => {
          this._setStatus('正在搜索设备...');
          console.log('正在搜索设备...');
          // 监听找到新设备事件
          wx.onBluetoothDeviceFound((res) => {
            const devices = res.devices;
            if (devices.length > 0) {
              this._setStatus('发现设备...');
              console.log('发现设备...，停止搜索');
              console.log(devices);
              // this.stopSearch();
              this.deviceList = devices;
              if (this.callbacks.onDeviceFound) {
                this.callbacks.onDeviceFound(this.deviceList);
              }
            }
          });
          // 搜索20秒后自动停止
          this.timer = setTimeout(() => {
            console.log('搜索20秒后自动停止...，停止搜索');
            this.stopSearch();
            resolve(this.deviceList);
          }, 10000);
        },
        fail: (err) => {
          console.error('搜索设备失败:');
          console.log(err);
          reject(err);
        },
      });
    });
  }

  /**
   * 停止搜索设备
   */
  stopSearch() {
    wx.stopBluetoothDevicesDiscovery();
    this._setStatus('已停止搜索');
    if (this.callbacks.onStopSearch) {
      this.callbacks.onStopSearch();
    }
  }
  /**
   * 重新搜索设备
   */
  reSearch() {
    return new Promise((resolve, reject) => {
      // 1. 一直没搜索到设备，重新搜索
      if (this.deviceList.length === 0) {
        this.searchDevices();
        resolve(null);
        return;
      }
      // 2. 没连接成功过，重新搜索
      if (this.deviceId === '') {
        this.searchDevices();
        resolve(null);
        return;
      }
      // 2. 开始搜索前，先获取所有已发现的设备列表（关键步骤）
      wx.getBluetoothDevices({
        success: (res) => {
          const devices = res.devices;
          // 遍历设备列表，检查你的目标设备是否已经在其中
          if (devices && devices.length > 0) {
            const targetDevice = devices.find(device => device.deviceId === this.deviceId); // 请替换为你的设备名称或识别条件
            if (targetDevice) {
              console.log('从缓存列表中找到设备', targetDevice);
              wx.closeBLEConnection({
                deviceId: this.deviceId,
                success: () => {
                  if (this.callbacks.onDisconnected) {
                    this.callbacks.onDisconnected();
                  }
                  resolve(targetDevice); // 如果找到，可以考虑直接返回，不再启动新搜索，或者根据需求决定
                }
              });
              //resolve(targetDevice); // 如果找到，可以考虑直接返回，不再启动新搜索，或者根据需求决定
            }
          } else {
            console.log('从缓存列表中没找到设备，重新搜索');
            resolve(null);
            // 4. 如果缓存列表中没有，再启动发现新设备的监听
            this.searchDevices();
          }
        },
        fail: (err) => {
          console.log('重新搜索设备异常', err);
          if (err.errCode === 10002) {
            // 没有找到指定设备
            this.searchDevices();
          } else {
            this.initBluetooth();
          }
          reject(err);
        }
      });
    });
  }
  /**
   * 连接指定设备
   */
  connectDevice(deviceId) {
    return new Promise((resolve, reject) => {
      wx.createBLEConnection({
        deviceId: deviceId,
        success: (res) => {
          this._getBLEDeviceServices(deviceId)
            .then(() => {
              this.deviceId = deviceId;
              this._setStatus('设备连接成功');
              console.log('设备连接成功');
              this.connected = true;
              if (this.callbacks.onConnected) {
                this.callbacks.onConnected(deviceId);
              }
              resolve(res);
            })
            .catch(err => reject(err));
        },
        fail: (err) => {
          console.log('设备连接失败：');
          console.log(err);
          this._setStatus('设备连接失败');
          reject(err);
        }
      });
    });
  }

  /**
   * 获取蓝牙服务
   */
  _getBLEDeviceServices(deviceId) {
    return new Promise((resolve, reject) => {
      wx.getBLEDeviceServices({
        deviceId: deviceId,
        success: (res) => {
          const services = res.services;
          if (services.length > 0) {
            this._setStatus('获取到打印服务');
            console.log('获取到打印服务');
            this.serviceId = services[0].uuid;
            return this._getBLEDeviceCharacteristics(deviceId, this.serviceId)
              .then(resolve)
              .catch(reject);
          }
          // for (const service of res.services) {
          //   // 通常蓝牙打印机的服务UUID是FFE0或FF00
          //   if (service.uuid.startsWith('FFE0') || service.uuid.startsWith('FF00')) {
          //     this._setStatus('获取到打印服务');
          //     this.serviceId = service.uuid;
          //     return this._getBLEDeviceCharacteristics(deviceId, service.uuid)
          //       .then(resolve)
          //       .catch(reject);
          //   }
          // }
          console.log('未找到打印服务');
          reject(new Error('未找到打印服务'));
        },
        fail: (err) => {
          console.log('获取蓝牙服务', err);
          reject(err);
        }
      });
    });
  }

  /**
   * 获取蓝牙特征值
   */
  _getBLEDeviceCharacteristics(deviceId, serviceId) {
    return new Promise((resolve, reject) => {
      wx.getBLEDeviceCharacteristics({
        deviceId: deviceId,
        serviceId: serviceId,
        success: (res) => {
          for (const characteristic of res.characteristics) {
            // 寻找可写的特征值
            if (characteristic.properties.write) {
              this._setStatus('获取到可写特征值');
              console.log('获取到可写特征值');
              this.characteristicId = characteristic.uuid;
              this.connected = true;
              resolve();
              return;
            }
          }
          console.log('未找到可写特征值');
          reject(new Error('未找到可写特征值'));
        },
        fail: (err) => {
          console.log('获取蓝牙特征值', err);
          reject(err);
        }
      });
    });
  }

  /**
   * 断开连接
   */
  disconnect() {
    this.stopSearch();
    wx.closeBluetoothAdapter();
    clearTimeout(this.timer);
    if (this.deviceId) {
      wx.closeBLEConnection({
        deviceId: this.deviceId,
        success: () => {
          this._reset();
          if (this.callbacks.onDisconnected) {
            this.callbacks.onDisconnected();
          }
        }
      });
    }
  }


  /**
   * 重置连接状态
   */
  _reset() {
    this.deviceId = '';
    this.serviceId = '';
    this.characteristicId = '';
    this.connected = false;
    this.deviceList = [];
  }

  /**
   * 发送打印数据
   */
  print(data) {
    if (!this.connected) {
      return Promise.reject(new Error('打印机未连接'));
    }

    return new Promise((resolve, reject) => {
      // 确保数据是ArrayBuffer格式
      let buffer;
      if (typeof data === 'string') {
        buffer = this._stringToArrayBuffer(data);
      } else if (data instanceof Array) {
        buffer = new Uint8Array(data).buffer;
      } else {
        buffer = data;
      }

      // 分片传输大数据[2](@ref)
      if (buffer.byteLength > 20) {
        this._sendLargeData(buffer, resolve, reject);
      } else {
        this._sendDataChunk(buffer, resolve, reject);
      }
    });
  }

  /**
   * 分片发送大数据
   */
  _sendLargeData(buffer, resolve, reject) {
    const chunkSize = 18; // 预留2字节给协议头
    const dataView = new Uint8Array(buffer);
    let offset = 0;

    const sendNextChunk = () => {
      if (offset >= dataView.length) {
        resolve();
        return;
      }

      const chunk = dataView.slice(offset, Math.min(offset + chunkSize, dataView.length));
      this._sendDataChunk(chunk.buffer, () => {
        offset += chunkSize;
        setTimeout(sendNextChunk, 50); // 控制发送间隔
      }, reject);
    };

    sendNextChunk();
  }

  /**
   * 发送数据块
   */
  _sendDataChunk(buffer, resolve, reject) {
    wx.writeBLECharacteristicValue({
      deviceId: this.deviceId,
      serviceId: this.serviceId,
      characteristicId: this.characteristicId,
      value: buffer,
      success: resolve,
      fail: reject
    });
  }

  /**
   * 打印文本
   */
  printText(text, options = {}) {
    const commands = [];

    // 初始化打印机
    commands.push(0x1B, 0x40); // ESC @ 初始化

    // 设置对齐方式
    if (options.align === 'center') {
      commands.push(0x1B, 0x61, 0x01); // 居中
    } else if (options.align === 'right') {
      commands.push(0x1B, 0x61, 0x02); // 居右
    } else {
      commands.push(0x1B, 0x61, 0x00); // 居左
    }

    // 设置字体大小
    if (options.size === 'large') {
      commands.push(0x1D, 0x21, 0x11); // 双倍宽高
    } else if (options.size === 'medium') {
      commands.push(0x1B, 0x21, 0x10); // 双倍高度
    } else {
      commands.push(0x1B, 0x21, 0x00); // 正常大小
    }

    // 添加文本内容
    this._addTextToCommand(commands, text);

    // 换行
    commands.push(0x0A);

    return this.print(commands);
  }

  /**
   * 打印订单小票
   */
  printReceipt(orderInfo) {
    const commands = [];

    // 初始化打印机
    commands.push(0x1B, 0x40);

    // 标题（大字体、居中）
    commands.push(0x1B, 0x61, 0x01, 0x1D, 0x21, 0x11);
    this._addTextToCommand(commands, `${orderInfo.title || '订单小票'}\n`);

    // 订单信息（正常字体）
    commands.push(0x1D, 0x21, 0x00, 0x1B, 0x61, 0x00);
    this._addTextToCommand(commands, `订单号: ${orderInfo.orderNo}\n`);
    this._addTextToCommand(commands, `时间: ${orderInfo.time}\n\n`);

    // 商品列表
    this._addTextToCommand(commands, "----------------------------\n");
    orderInfo.items.forEach(item => {
      const line = `${item.name} x${item.quantity} ¥${item.price}\n`;
      this._addTextToCommand(commands, line);
    });
    this._addTextToCommand(commands, "----------------------------\n");

    // 总计
    this._addTextToCommand(commands, `总计: ¥${orderInfo.total}\n\n`);

    // 切纸[6](@ref)
    commands.push(0x1D, 0x56, 0x42, 0x00);

    return this.print(commands);
  }

  /**
   * 添加文本到命令数组
   */
  _addTextToCommand(commands, text) {
    for (let i = 0; i < text.length; i++) {
      commands.push(text.charCodeAt(i));
    }
  }

  /**
   * 字符串转ArrayBuffer
   */
  _stringToArrayBuffer(str) {
    const buffer = new ArrayBuffer(str.length);
    const dataView = new Uint8Array(buffer);
    for (let i = 0; i < str.length; i++) {
      dataView[i] = str.charCodeAt(i);
    }
    return buffer;
  }

  /**
   * 设置状态回调
   */
  onStatusChange(callback) {
    this.callbacks.onStatusChange = callback;
  }

  /**
   * 设置设备发现回调
   */
  onDeviceFound(callback) {
    this.callbacks.onDeviceFound = callback;
  }

  /**
   * 设置连接成功回调
   */
  onConnected(callback) {
    this.callbacks.onConnected = callback;
  }

  /**
   * 设置断开连接回调
   */
  onDisconnected(callback) {
    this.callbacks.onDisconnected = callback;
  }

  onStopSearch(callback) {
    this.callbacks.onStopSearch = callback;
  }

  /**
   * 更新状态
   */
  _setStatus(status) {
    if (this.callbacks.onStatusChange) {
      this.callbacks.onStatusChange(status);
    }
  }

  /**
   * 获取连接状态
   */
  isConnected() {
    return this.connected;
  }

  /**
   * 获取设备列表
   */
  getDeviceList() {
    return this.deviceList;
  }
}

// 创建单例实例
const printer = new BluetoothPrinter();

export default printer;